﻿using Infrastructure;
using Infrastructure.Pub;
using Infrastructure.Tool;
using Senparc.Weixin;
using Senparc.Weixin.MP;
using Senparc.Weixin.MP.AdvancedAPIs;
using Senparc.Weixin.MP.AdvancedAPIs.OAuth;
using Senparc.Weixin.MP.TenPayLibV3;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
using DormMS.IService;
using DormMS.IService.Common;
using DormMS.Model;
using DormMS.Model.ViewModels;

namespace WeChat.Controllers
{
    public class OrderPaymentController : Controller
    {
        //private string appId = WsdConfig.GetAppString("AppId");
        //private string secret = WsdConfig.GetAppString("AppSecret");
        //private string key = WsdConfig.GetAppString("Key");
        //private string mchId = WsdConfig.GetAppString("MchId");


        private string appId;
        private string secret;
        private string key;
        private string mchId;
        private string tenpayNotify = WsdConfig.GetAppString("TenpayNotify");
        private string checkUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={0}";//用来验证accesstoken有效性的地址

        private IOrderService _orderService;
        private IMemberService _memberService;
        private IWxConfigService _configService;
        private ILogService logService;
        private IGroupHeadService _groupheadservice;
        public OrderPaymentController(IOrderService orderService, IMemberService memberService, IWxConfigService configService, ILogService l, IGroupHeadService groupheadservice)
        {
            _orderService = orderService;
            _memberService = memberService;
            _configService = configService;
            logService = l;
            _groupheadservice = groupheadservice;
            var config = _configService.GetConfig();
            appId = config.AppId;
            secret = config.AppSecret;
            key = config.PaySignKey;
            mchId = config.PartnerID;
        }

        public ActionResult Index(int orderId)
        {
            string mid = PubGet.GetMemberId;
            if (!string.IsNullOrEmpty(mid))
            {
                Order order = _orderService.GetOrderInfo(orderId);
                if (order.OrderType == DormMS.Model.Enum.OrderType.积分订单)
                {
                    return Content("你访问的页面不存在");
                }
                Member member = _memberService.GetMemberInfo(int.Parse(mid));
                ViewBag.order = order;
                ViewBag.orderId = orderId;
                return View(member);
            }
            else
            {
                return Redirect("/Wx/Index?returnUrl=" + Request.Url);
            }

        }

        public ActionResult Recharge(int id)
        {
            string mid = PubGet.GetMemberId;
            if (!string.IsNullOrEmpty(mid))
            {
                MemberRecharge order = _memberService.GetMemberRecharge(id);
                ViewBag.order = order;
                ViewBag.id = id;
                return View();
            }
            else
            {
                return Redirect("/Wx/Index?returnUrl=" + Request.Url);
            }
        }

        public JsonResult GetRechargeInfo(int id)
        {
            Infrastructure.Result re = new Infrastructure.Result();
            try
            {
                MemberRecharge model = _memberService.GetMemberRecharge(id);
                if (model == null)
                {
                    re.msg = "充值订单不存在";
                    return Json(re);
                }

                string mid = PubGet.GetMemberId;
                Member member = _memberService.GetMemberInfo(int.Parse(mid));
                string openId = member.OpenId;
                string timeStamp = "";
                string nonceStr = "";
                string paySign = "";
                string sp_billno = model.PayNo;

                //创建支付应答对象
                RequestHandler packageReqHandler = new RequestHandler(null);
                //初始化
                packageReqHandler.Init();

                timeStamp = TenPayV3Util.GetTimestamp();
                nonceStr = TenPayV3Util.GetNoncestr();



                //设置package订单参数
                packageReqHandler.SetParameter("appid", appId);          //公众账号ID
                packageReqHandler.SetParameter("mch_id", mchId);         //商户号
                packageReqHandler.SetParameter("nonce_str", nonceStr);                    //随机字符串
                packageReqHandler.SetParameter("body", "订单支付");    //商品信息
                packageReqHandler.SetParameter("out_trade_no", sp_billno);      //商家订单号
                packageReqHandler.SetParameter("total_fee", (model.Amount * 100).ToString("0"));                    //商品金额,以分为单位(money * 100).ToString()
                //packageReqHandler.SetParameter("total_fee", "1");                                                                                                           //packageReqHandler.SetParameter("total_fee", "1");
                packageReqHandler.SetParameter("spbill_create_ip", Request.UserHostAddress);   //用户的公网ip，不是商户服务器IP
                packageReqHandler.SetParameter("notify_url", tenpayNotify);          //接收财付通通知的URL
                packageReqHandler.SetParameter("trade_type", TenPayV3Type.JSAPI.ToString());                        //交易类型
                packageReqHandler.SetParameter("openid", openId);                      //用户的openId

                string sign = packageReqHandler.CreateMd5Sign("key", key);
                packageReqHandler.SetParameter("sign", sign);                       //签名

                string data = packageReqHandler.ParseXML();

                var result = TenPayV3.Unifiedorder(data);
                var res = XDocument.Parse(result);
                string prepayId = "";
                if (res.Element("xml").Element("prepay_id") != null)
                {
                    prepayId = res.Element("xml").Element("prepay_id").Value;
                }

                //设置支付参数
                RequestHandler paySignReqHandler = new RequestHandler(null);
                paySignReqHandler.SetParameter("appId", appId);
                paySignReqHandler.SetParameter("timeStamp", timeStamp);
                paySignReqHandler.SetParameter("nonceStr", nonceStr);
                paySignReqHandler.SetParameter("package", string.Format("prepay_id={0}", prepayId));
                paySignReqHandler.SetParameter("signType", "MD5");
                paySign = paySignReqHandler.CreateMd5Sign("key", key);




                WxPayModel wm = new WxPayModel();
                wm.appId = appId;
                wm.nonceStr = nonceStr;

                wm.timeStamp = timeStamp;
                wm.package = string.Format("prepay_id={0}", prepayId);
                wm.paySign = paySign;
                re.model = model;
                re.data = wm;
                re.isSuccess = true;
            }
            catch (Exception ex)
            {

                re.msg = ex.Message;
            }
            return Json(re);
        }


        public JsonResult Use(decimal totalpay, bool isUseBalance)
        {
            Infrastructure.Result result = new Infrastructure.Result();

            try
            {
                string mid = PubGet.GetMemberId;
                decimal r = 0;
                Member member = _memberService.GetMemberInfo(int.Parse(mid));

                if (isUseBalance)
                {
                    r = totalpay - member.Balance;
                    if (r < 0)
                    {
                        r = 0;
                    }
                }
                else
                {
                    r = totalpay;
                }
                result.data = r;

                result.isSuccess = true;
            }
            catch (Exception ex)
            {

                result.msg = ex.Message;
            }
            return Json(result);
        }

        public JsonResult ToPay(int orderId, bool isUseBalance)
        {
            Infrastructure.Result re = new Infrastructure.Result();
            try
            {
                Order order = _orderService.GetOrderInfo(orderId);
                if (order == null)
                {
                    re.msg = "订单不存在";
                    return Json(re);
                }

                string mid = PubGet.GetMemberId;
                Member member = _memberService.GetMemberInfo(int.Parse(mid));
                if (order.OrderType == DormMS.Model.Enum.OrderType.团购订单)
                {
                    //order.GroupId
                    if (order.GroupId.HasValue)
                    {
                        var GroupModel = _groupheadservice.GetGroupHeadInfoByID(order.GroupId.Value);
                        if (GroupModel != null)
                        {
                            if (order.ProductPrice != GroupModel.NowPrice)
                            {
                                order.ProductPrice = GroupModel.NowPrice;
                                order.PayMoney = order.ProductPrice - order.MemberMoney;
                                _orderService.EditOrder(order);
                            }


                        }
                    }
                }


                if (isUseBalance && member.Balance > 0 && order.MemberMoney == 0)
                {
                    if (member.Balance >= order.PayMoney)
                    {
                        MemberBalanceDetail mbd = new MemberBalanceDetail();
                        mbd.MemberId = member.Id;
                        mbd.Amount = order.PayMoney * -1;
                        mbd.Point = 0;
                        mbd.OrderId = order.Id;
                        mbd.OrderNo = order.OrderNo;
                        mbd.Note = "订单" + order.OrderNo + "消费";
                        _memberService.AddMemberBalanceDetail(mbd);

                        order.MemberMoney = order.PayMoney;
                        order.PayMoney = 0;
                        _orderService.EditOrder(order);
                        OrderRecord or = new OrderRecord();
                        or.OperationId = order.MemberId;
                        or.OperationUserType = 0;
                        or.ClientName = "微信";
                        _orderService.PayOrder(order.OrderNo, or);
                        order = _orderService.GetOrderInfo(orderId);
                        re.isSuccess = true;
                        re.model = order;
                        return Json(re);
                    }
                    else
                    {
                        MemberBalanceDetail mbd = new MemberBalanceDetail();
                        mbd.MemberId = member.Id;
                        mbd.Amount = member.Balance * -1;
                        mbd.Point = 0;
                        mbd.OrderId = order.Id;
                        mbd.OrderNo = order.OrderNo;
                        mbd.Note = "订单" + order.OrderNo + "消费";
                        _memberService.AddMemberBalanceDetail(mbd);

                        order.PayMoney = order.PayMoney - member.Balance;
                        order.MemberMoney = member.Balance;
                        _orderService.EditOrder(order);
                    }
                }

                //if (order.MemberMoney > 0)
                //{
                //    if (member.Balance > 0)
                //    {
                //        if (member.Balance < order.MemberMoney)
                //        {
                //            order.PayMoney = order.PayMoney + order.MemberMoney - member.Balance;
                //            order.MemberMoney = member.Balance;
                //            _orderService.UpdateOrder(order);
                //        }
                //    }
                //    else
                //    {
                //        order.PayMoney = order.PayMoney + order.MemberMoney;
                //        order.MemberMoney = 0;
                //        _orderService.UpdateOrder(order);
                //    }
                //}

                string openId = member.OpenId;
                string timeStamp = "";
                string nonceStr = "";
                string paySign = "";
                string sp_billno = order.OrderNo;

                //创建支付应答对象
                RequestHandler packageReqHandler = new RequestHandler(null);
                //初始化
                packageReqHandler.Init();

                timeStamp = TenPayV3Util.GetTimestamp();
                nonceStr = TenPayV3Util.GetNoncestr();



                //设置package订单参数
                packageReqHandler.SetParameter("appid", appId);          //公众账号ID
                packageReqHandler.SetParameter("mch_id", mchId);         //商户号
                packageReqHandler.SetParameter("nonce_str", nonceStr);                    //随机字符串
                packageReqHandler.SetParameter("body", "订单支付");    //商品信息
                packageReqHandler.SetParameter("out_trade_no", sp_billno);      //商家订单号
                packageReqHandler.SetParameter("total_fee", (order.PayMoney * 100).ToString("0"));                    //商品金额,以分为单位(money * 100).ToString()
                //packageReqHandler.SetParameter("total_fee", "1");                                                                                                        //packageReqHandler.SetParameter("total_fee", "1");
                packageReqHandler.SetParameter("spbill_create_ip", Request.UserHostAddress);   //用户的公网ip，不是商户服务器IP
                packageReqHandler.SetParameter("notify_url", tenpayNotify);          //接收财付通通知的URL
                packageReqHandler.SetParameter("trade_type", TenPayV3Type.JSAPI.ToString());                        //交易类型
                packageReqHandler.SetParameter("openid", openId);                      //用户的openId

                string sign = packageReqHandler.CreateMd5Sign("key", key);
                packageReqHandler.SetParameter("sign", sign);                       //签名

                string data = packageReqHandler.ParseXML();

                var result = TenPayV3.Unifiedorder(data);
                var res = XDocument.Parse(result);
                string prepayId = "";
                if (res.Element("xml").Element("prepay_id") != null)
                {
                    prepayId = res.Element("xml").Element("prepay_id").Value;
                }

                //设置支付参数
                RequestHandler paySignReqHandler = new RequestHandler(null);
                paySignReqHandler.SetParameter("appId", appId);
                paySignReqHandler.SetParameter("timeStamp", timeStamp);
                paySignReqHandler.SetParameter("nonceStr", nonceStr);
                paySignReqHandler.SetParameter("package", string.Format("prepay_id={0}", prepayId));
                paySignReqHandler.SetParameter("signType", "MD5");
                paySign = paySignReqHandler.CreateMd5Sign("key", key);




                WxPayModel wm = new WxPayModel();
                wm.appId = appId;
                wm.nonceStr = nonceStr;

                wm.timeStamp = timeStamp;
                wm.package = string.Format("prepay_id={0}", prepayId);
                wm.paySign = paySign;
                re.model = order;
                re.data = wm;
                re.isSuccess = true;
            }
            catch (Exception ex)
            {

                re.msg = ex.Message;
            }
            return Json(re);

        }

        public JsonResult GetOrderPay(int orderid)
        {
            Infrastructure.Result re = new Infrastructure.Result();
            try
            {
                Order order = _orderService.GetOrderInfo(orderid);
                if (order == null)
                {
                    re.msg = "订单不存在";
                    return Json(re);
                }

                re.model = order;
                re.isSuccess = true;
            }
            catch (Exception ex)
            {

                re.msg = ex.Message;
            }
            return Json(re);
        }


        public ActionResult PayNotifyUrl()
        {

            ResponseHandler resHandler = new ResponseHandler(null);

            string return_code = resHandler.GetParameter("return_code");
            string return_msg = resHandler.GetParameter("return_msg");
            string transaction_id = resHandler.GetParameter("transaction_id");
            string out_trade_no = resHandler.GetParameter("out_trade_no");

            logService.OperationLog(0, "", Request.RawUrl,
                           out_trade_no + "微信回调","", Generator.GetIP());

            resHandler.SetKey(key);

            try
            {
                //验证请求是否从微信发过来（安全）
                if (resHandler.IsTenpaySign())
                {

                    //正确的订单处理
                    if (!string.IsNullOrEmpty(transaction_id))
                    {

                        string nonceStr = TenPayV3Util.GetNoncestr();
                        RequestHandler packageReqHandler = new RequestHandler(null);


                        //设置package订单参数
                        packageReqHandler.SetParameter("appid", appId);          //公众账号ID
                        packageReqHandler.SetParameter("mch_id", mchId);         //商户号
                        packageReqHandler.SetParameter("transaction_id", transaction_id);       //填入微信订单号 
                        packageReqHandler.SetParameter("out_trade_no", out_trade_no);         //填入商家订单号
                        packageReqHandler.SetParameter("nonce_str", nonceStr);             //随机字符串
                        string sign = packageReqHandler.CreateMd5Sign("key", key);
                        packageReqHandler.SetParameter("sign", sign);                       //签名

                        string data = packageReqHandler.ParseXML();
                        //查询订单
                        var result = TenPayV3.OrderQuery(data);
                        var res = XDocument.Parse(result);
                        string trade_state = "";
                        if (res.Element("xml").Element("trade_state") != null)
                        {
                            trade_state = res.Element("xml").Element("trade_state").Value;
                        }

                        if (trade_state == "SUCCESS")
                        {
                            //充值
                            if (out_trade_no.Substring(0, 1) == "R")
                            {
                                _memberService.RechargeSuccess(out_trade_no);
                            }
                            else//订单
                            {
                                Order order = _orderService.GetOrderInfo(out_trade_no);
                                if (order != null)
                                {
                                    OrderRecord or = new OrderRecord();
                                    or.OperationId = order.MemberId;
                                    or.OperationUserType = 0;
                                    or.ClientName = "微信";
                                    _orderService.PayOrder(out_trade_no, or);
                                }
                                else
                                {
                                    return_code = "FAIL";
                                    return_msg = "未查到本地订单";
                                }
                            }
                        }
                        else
                        {
                            return_code = "FAIL";
                            return_msg = "未查到微信订单";
                        }

                    }
                }
                else
                {

                    logService.OperationLog(0, "", Request.RawUrl,
                           out_trade_no + "付款失败", "错误的订单", Generator.GetIP());
                    //错误的订单处理
                }
            }
            catch (Exception ex)
            {
                return_code = "FAIL";
                return_msg = ex.InnerException.Message;
                logService.OperationLog(0, "", Request.RawUrl,
                           out_trade_no+"付款失败", ex.Message, Generator.GetIP());
            }

            string xml = string.Format(@"<xml>
   <return_code><![CDATA[{0}]]></return_code>
   <return_msg><![CDATA[{1}]]></return_msg>
</xml>", return_code, return_msg);

            logService.OperationLog(0, "", Request.RawUrl,
                           out_trade_no + "付款", xml, Generator.GetIP());

            return Content(xml, "text/xml");
        }


        public JsonResult GetOrderPayInfo(int orderId)
        {
            Infrastructure.Result result = new Infrastructure.Result();
            try
            {
                //loggerService.Info(Types.LogType.微信支付, "查询订单" + orderId, 0);
                Order order = _orderService.GetOrderInfo(orderId);
                if (order != null)
                {
                    if (order.PayState == DormMS.Model.Enum.OrderPayStatus.已支付)
                    {
                        result.isSuccess = true;

                    }
                    else
                    {
                        result.msg = "订单支付消息还未回传，请稍后";
                    }
                }
                else
                {
                    result.msg = "订单不存在";
                }
            }
            catch (Exception ex)
            {
                result.msg = ex.Message;
            }
            //loggerService.Info(Types.LogType.微信支付, result.msg, 0);
            return Json(result);
        }

        public JsonResult GetMemberRechargeInfo(int id)
        {
            Infrastructure.Result result = new Infrastructure.Result();
            try
            {
                //loggerService.Info(Types.LogType.微信支付, "查询订单" + orderId, 0);
                MemberRecharge order = _memberService.GetMemberRecharge(id);
                if (order != null)
                {
                    if (order.Status == DormMS.Model.Enum.OrderPayStatus.已支付)
                    {
                        result.isSuccess = true;

                    }
                    else
                    {
                        result.msg = "订单支付消息还未回传，请稍后";
                    }
                }
                else
                {
                    result.msg = "订单不存在";
                }
            }
            catch (Exception ex)
            {
                result.msg = ex.Message;
            }
            //loggerService.Info(Types.LogType.微信支付, result.msg, 0);
            return Json(result);
        }
    }
}